package config

import (
	"crypto/rand"
	"math/big"

	"github.com/spf13/viper"
	"github.com/toolkits/file"
)

type Config struct {
	Port         string
	DatabasePath string
	JWTSecret    string
	LogLevel     string
	LogDir       string
}

func Load() (*Config, error) {

	configFileName := "config.yaml"
	if !file.IsExist(configFileName) {
		if err := NewDefaultConfigFile(configFileName); err != nil {

		}
	}
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")
	viper.AddConfigPath(".")
	viper.AddConfigPath("./config")

	if err := viper.ReadInConfig(); err != nil {
		return nil, err
	}

	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		return nil, err
	}

	return &config, nil
}

func NewDefaultConfigFile(configFileName string) error {
	viper.SetDefault("Port", "8080")
	viper.SetDefault("DatabasePath", "db.sqlite")

	secret, err := NewRandomSecret(36)
	if err != nil {
		return err
	}
	viper.SetDefault("JWTSecret", secret)

	viper.SetDefault("LogLevel", "info")
	viper.SetDefault("LogDir", "./logs")

	return viper.WriteConfigAs(configFileName)
}

func NewRandomSecret(length int) (string, error) {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		randomIndex, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
		if err != nil {
			return "", err
		}
		b[i] = charset[randomIndex.Int64()]
	}
	return string(b), nil
}
